#include "networking.h"
#include <pthread.h>

using namespace std;

/*
 * The second approach, uses pthread
 */

int      debug=0;
uint16_t serverport=21;
char     *hostname=NULL;

socketstream *ss;
int           sockfd;

void* copy_to(void *arg);   // the thread to read from the user

static void
parse_args(int argc, char** argv) 
{
  int n = 1;
  while (n < argc) {
    if (strcmp(argv[n], "-h") == 0) {
      hostname = argv[++n];
    } else if (strcmp(argv[n], "-d") == 0) {
      debug = 1;
    } else if (strcmp(argv[n], "-p") == 0) {
      serverport = atoi(argv[++n]);
    } else
      err_quit("usage: %s [-h <hostname>] [-p <port>] [-d]", argv[0]);
    n++;
  }
  if (hostname == NULL)
    err_quit("usage: %s [-h <hostname>] [-p <port>] [-d]", argv[0]);  
}

int
main(int argc, char **argv)
{
  struct sockaddr_in	        servaddr;
  struct in_addr		**pptr;
  struct hostent		*hp;

  parse_args(argc, argv);

  // create a socket
  if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    err_quit("Cannot creat socket!");
  }
  
  // get server address
  if ( (hp = gethostbyname(hostname)) == NULL) {
    err_quit("Cannot resovle hostname!");
  }

  // parse the addresses
  pptr = (struct in_addr **) hp->h_addr_list;
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(serverport);
  memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
  char charname[MAXLINE];
  if (debug) cerr << "Connect to server " << inet_ntop(AF_INET, &servaddr.sin_addr, charname, sizeof(charname)) << endl;
    
  // connect to the server
  if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {
    close(sockfd);
    err_quit("Cannot connect to server!");
  }

  char	recvline[MAXLINE + 1];
  ss = new socketstream(sockfd);

  pthread_t  tid;
  if (pthread_create(&tid, NULL, copy_to, NULL)) {
    err_quit("pthread_creat()");
  }

  while  (ss->read_line(recvline, MAXLINE) > 0) {
    fprintf(stdout, "%s\n", recvline);
  }  
}

void *copy_to(void *arg) {
  char sendline[MAXLINE];

  if (debug) cout << "Thread create()!" << endl;
  while (fgets(sendline, sizeof(sendline), stdin))
    ss->writen_socket(sendline, strlen(sendline));
  
  shutdown(sockfd, SHUT_WR);
  if (debug) cout << "Thread done!" << endl;

  pthread_exit(0);
}
